const winston = require('winston');
const path = require('path');
const config = require('../config/config');

/**
 * 日志配置说明：
 * - 文件日志：只记录警告(warn)和错误(error)级别
 * - 控制台日志：显示信息(info)及以上级别的所有日志
 * - 错误日志：单独记录到error.log文件
 */

/**
 * 优化长字符串用于日志记录
 * @param {string} str - 原始字符串
 * @param {number} maxLength - 最大长度，默认200
 * @param {number} prefixLength - 前缀长度，默认100
 * @param {number} suffixLength - 后缀长度，默认100
 * @returns {string} 优化后的字符串
 */
function truncateForLog(str, maxLength = 200, prefixLength = 100, suffixLength = 100) {
  if (typeof str !== 'string' || str.length <= maxLength) {
    return str;
  }
  
  const prefix = str.substring(0, prefixLength);
  const suffix = str.substring(str.length - suffixLength);
  return `${prefix}...${suffix} (总长度: ${str.length})`;
}

/**
 * 优化对象中的长字符串用于日志记录
 * @param {object} obj - 原始对象
 * @param {number} maxLength - 最大长度，默认200
 * @returns {object} 优化后的对象
 */
function optimizeObjectForLog(obj, maxLength = 200) {
  if (!obj || typeof obj !== 'object') {
    return obj;
  }
  
  const optimized = { ...obj };
  
  // 递归处理对象
  function processValue(value) {
    if (typeof value === 'string') {
      return truncateForLog(value, maxLength);
    } else if (Array.isArray(value)) {
      return value.map(processValue);
    } else if (value && typeof value === 'object') {
      const processed = {};
      for (const [key, val] of Object.entries(value)) {
        processed[key] = processValue(val);
      }
      return processed;
    }
    return value;
  }
  
  return processValue(optimized);
}

// 确保日志目录存在
const fs = require('fs');
const logDir = path.dirname(config.logging.file);
if (!fs.existsSync(logDir)) {
  fs.mkdirSync(logDir, { recursive: true });
}

// 公共时间戳格式
const timestampFormat = winston.format.timestamp({
  format: 'YYYY-MM-DD HH:mm:ss'
});

// 公共错误格式
const errorFormat = winston.format.errors({ stack: true });

// 控制台美化格式
const consoleFormat = winston.format.printf(({ level, message, timestamp, service, ...meta }) => {
  const levelColors = {
    error: '\x1b[31m',   // 红色
    warn: '\x1b[33m',    // 黄色
    info: '\x1b[36m',    // 青色
    debug: '\x1b[35m',   // 紫色
    verbose: '\x1b[37m'  // 白色
  };
  
  const reset = '\x1b[0m';
  const bold = '\x1b[1m';
  const dim = '\x1b[2m';
  
  const levelColor = levelColors[level] || '\x1b[37m';
  const levelTag = `${levelColor}${bold}[${level.toUpperCase()}]${reset}`;
  const timeTag = `${dim}${timestamp}${reset}`;
  const serviceTag = `${dim}[${service}]${reset}`;
  let logLine = `${timeTag} ${levelTag} ${serviceTag} ${message}`;
  
  // 格式化元数据
  if (Object.keys(meta).length > 0) {
    const metaStr = JSON.stringify(meta, null, 2)
      .split('\n')
      .map(line => `${dim}  ${line}${reset}`)
      .join('\n');
    logLine += `\n${metaStr}`;
  }
  
  return logLine;
});

// 文件日志格式
const fileFormat = winston.format.printf(({ level, message, timestamp, service, ...meta }) => {
  let logLine = `${timestamp} [${level.toUpperCase()}] [${service}] ${message}`;
  
  if (Object.keys(meta).length > 0) {
    logLine += ` ${JSON.stringify(meta)}`;
  }
  
  return logLine;
});

// 公共文件传输配置
const createFileTransport = (filename, level, maxSize = 10485760, maxFiles = 10) => {
  return new winston.transports.File({ 
    filename,
    level,
    format: winston.format.combine(timestampFormat, errorFormat, fileFormat),
    maxsize: maxSize,
    maxFiles,
    tailable: true
  });
};

const logger = winston.createLogger({
  level: config.logging.level,
  defaultMeta: { service: path.basename(require.main.filename) },
  transports: [
    // 警告和错误日志文件 - 只记录warn和error级别
    createFileTransport(config.logging.file, 'warn'),
    
    // 错误日志单独文件
    createFileTransport(path.join(logDir, 'error.log'), 'error', 5242880, 5)
  ],
  // 异常处理
  exceptionHandlers: [
    createFileTransport(path.join(logDir, 'exceptions.log'), 'error')
  ],
  rejectionHandlers: [
    createFileTransport(path.join(logDir, 'rejections.log'), 'error')
  ]
});

// 开发环境添加美化的控制台输出 - 显示所有级别的日志
if (config.server.env !== 'production') {
  logger.add(new winston.transports.Console({
    level: 'info', // 控制台显示info及以上级别的所有日志
    format: winston.format.combine(
      winston.format.timestamp({
        format: 'HH:mm:ss'
      }),
      errorFormat,
      consoleFormat
    ),
    handleExceptions: true,
    handleRejections: true
  }));
}

module.exports = {
  logger,
  truncateForLog,
  optimizeObjectForLog
};
